﻿//
// Created by 17616 on 2021/3/20.
//

#include <stdarg.h>
#include "public.h"
#include <regex>
//替换字符串
std::string &replace_str(std::string &str, const std::string &to_replaced, const std::string &newchars) {
    for (std::string::size_type pos(0); pos != std::string::npos; pos += newchars.length()) {
        pos = str.find(to_replaced, pos);
        if (pos != std::string::npos) {
            str.replace(pos, to_replaced.length(), newchars);
        } else {
            break;
        }
    }
    return str;
}


double GetTimer(std::string name) {
    std::smatch results;
    std::string str;
    if (!regex_search(name, results, std::regex("\\d+\\^\\d+us"))) {
        if (regex_search(name, results, std::regex("\\d+us"))) {
//            std::cout << results[0] << std::endl;
            str = results[0];
        }
        if (regex_search(str, results, std::regex("\\d+"))) {
//            std::cout << results[0] << std::endl;
            str = results[0];
        }
        return std::stod(str);
    } else {
        double a;
        double b;
        std::string str2 = results[0];
        if (regex_search(str2, results, std::regex("\\d+\\^"))) {
//            std::cout << results[0] << std::endl;
            str = results[0];
        }
        if (regex_search(str, results, std::regex("\\d+"))) {
//            std::cout << results[0] << std::endl;
            str = results[0];
        }
        a = std::stod(str);

        if (regex_search(str2, results, std::regex("\\d+us"))) {
//            std::cout << results[0] << std::endl;
            str = results[0];
        }
        if (regex_search(str, results, std::regex("\\d+"))) {
//            std::cout << results[0] << std::endl;
            str = results[0];
        }
        b = std::stod(str);
        return pow(a, b);
    }
}

std::string Format(const char *fmt, ...) {
    int len;
    std::string str;
    va_list args;
    char buffer[4 * 1024];
            va_start(args, fmt);
    if ((len = vsnprintf(buffer, sizeof(buffer), fmt, args)) > 0) {
        if (len < sizeof(buffer)) {
            str = buffer;
        } else {
            int maxsz = len + 1;
            char *buffer = (char *) malloc(maxsz);

            if (buffer) {
                len = vsnprintf(buffer, maxsz, fmt, args);

                if (len > 0 && len < maxsz) str = buffer;

                free(buffer);
            }
        }
    }
            va_end(args);
//    std::cout << str << std::endl;
    return str;
}


std::string GetFilePath(std::string file) {
    replace_str(file, "\\", "/");
    auto off = file.find_last_of('/');
    if (std::string::npos != off) {
        file = file.substr(0, off + 1);
        return file;
    } else {
        return std::string();
    }
}

std::string GetFileName(std::string file) {
    replace_str(file, "\\", "/");
    auto off = file.find_last_of('/');
    if (std::string::npos != off) {
        file = file.substr(off + 1, file.size() - off - 1);
    }
    return file;
}


std::string GetFilePathWithoutType(std::string file) {
    replace_str(file, "\\", "/");
    auto off = file.rfind('.');
    if (std::string::npos != off) {
        file = file.substr(0, off);
    }
    return file;
}


double WTable[256] = {
        0,//0
        0.0009765625,//1
        0.00390625,//2
        0.0087890625,//3
        0.015625,//4
        0.0244140625,//5
        0.03515625,//6
        0.0478515625,//7
        0.0625,//8
        0.0791015625,//9
        0.09765625,//10
        0.1181640625,//11
        0.140625,//12
        0.1650390625,//13
        0.19140625,//14
        0.2197265625,//15
        0.25,//16
        0.2822265625,//17
        0.31640625,//18
        0.3525390625,//19
        0.390625,//20
        0.4306640625,//21
        0.47265625,//22
        0.5166015625,//23
        0.5625,//24
        0.6103515625,//25
        0.66015625,//26
        0.7119140625,//27
        0.765625,//28
        0.8212890625,//29
        0.87890625,//30
        0.9384765625,//31
        1.0,//32
        1.0,//33
        1.0,//34
        1.0,//35
        1.0,//36
        1.0,//37
        1.0,//38
        1.0,//39
        1.0,//40
        1.0,//41
        1.0,//42
        1.0,//43
        1.0,//44
        1.0,//45
        1.0,//46
        1.0,//47
        1.0,//48
        1.0,//49
        1.0,//50
        1.0,//51
        1.0,//52
        1.0,//53
        1.0,//54
        1.0,//55
        1.0,//56
        1.0,//57
        1.0,//58
        1.0,//59
        1.0,//60
        1.0,//61
        1.0,//62
        1.0,//63
        1.0,//64
        1.0,//65
        1.0,//66
        1.0,//67
        1.0,//68
        1.0,//69
        1.0,//70
        1.0,//71
        1.0,//72
        1.0,//73
        1.0,//74
        1.0,//75
        1.0,//76
        1.0,//77
        1.0,//78
        1.0,//79
        1.0,//80
        1.0,//81
        1.0,//82
        1.0,//83
        1.0,//84
        1.0,//85
        1.0,//86
        1.0,//87
        1.0,//88
        1.0,//89
        1.0,//90
        1.0,//91
        1.0,//92
        1.0,//93
        1.0,//94
        1.0,//95
        1.0,//96
        1.0,//97
        1.0,//98
        1.0,//99
        1.0,//100
        1.0,//101
        1.0,//102
        1.0,//103
        1.0,//104
        1.0,//105
        1.0,//106
        1.0,//107
        1.0,//108
        1.0,//109
        1.0,//110
        1.0,//111
        1.0,//112
        1.0,//113
        1.0,//114
        1.0,//115
        1.0,//116
        1.0,//117
        1.0,//118
        1.0,//119
        1.0,//120
        1.0,//121
        1.0,//122
        1.0,//123
        1.0,//124
        1.0,//125
        1.0,//126
        1.0,//127
        1.0,//128
        1.0,//129
        1.0,//130
        1.0,//131
        1.0,//132
        1.0,//133
        1.0,//134
        1.0,//135
        1.0,//136
        1.0,//137
        1.0,//138
        1.0,//139
        1.0,//140
        1.0,//141
        1.0,//142
        1.0,//143
        1.0,//144
        1.0,//145
        1.0,//146
        1.0,//147
        1.0,//148
        1.0,//149
        1.0,//150
        1.0,//151
        1.0,//152
        1.0,//153
        1.0,//154
        1.0,//155
        1.0,//156
        1.0,//157
        1.0,//158
        1.0,//159
        1.0,//160
        1.0,//161
        1.0,//162
        1.0,//163
        1.0,//164
        1.0,//165
        1.0,//166
        1.0,//167
        1.0,//168
        1.0,//169
        1.0,//170
        1.0,//171
        1.0,//172
        1.0,//173
        1.0,//174
        1.0,//175
        1.0,//176
        1.0,//177
        1.0,//178
        1.0,//179
        1.0,//180
        1.0,//181
        1.0,//182
        1.0,//183
        1.0,//184
        1.0,//185
        1.0,//186
        1.0,//187
        1.0,//188
        1.0,//189
        1.0,//190
        1.0,//191
        1.0,//192
        1.0,//193
        1.0,//194
        1.0,//195
        1.0,//196
        1.0,//197
        1.0,//198
        1.0,//199
        1.0,//200
        1.0,//201
        1.0,//202
        1.0,//203
        1.0,//204
        1.0,//205
        1.0,//206
        1.0,//207
        1.0,//208
        1.0,//209
        1.0,//210
        1.0,//211
        1.0,//212
        1.0,//213
        1.0,//214
        1.0,//215
        1.0,//216
        1.0,//217
        1.0,//218
        1.0,//219
        1.0,//220
        1.0,//221
        1.0,//222
        1.0,//223
        1.0,//224
        1.0,//225
        1.0,//226
        1.0,//227
        1.0,//228
        1.0,//229
        1.0,//230
        1.0,//231
        1.0,//232
        1.0,//233
        1.0,//234
        1.0,//235
        1.0,//236
        1.0,//237
        1.0,//238
        1.0,//239
        1.0,//240
        1.0,//241
        1.0,//242
        1.0,//243
        1.0,//244
        1.0,//245
        1.0,//246
        1.0,//247
        1.0,//248
        1.0,//249
        1.0,//250
        1.0,//251
        1.0,//252
        1.0,//253
        0.25,//254
        0,//255
};

double LogTable[256] = {
        -3,//0
        0.0,//1
        0.6931471805599453,//2
        1.0986122886681098,//3
        1.3862943611198906,//4
        1.6094379124341003,//5
        1.791759469228055,//6
        1.9459101490553132,//7
        2.0794415416798357,//8
        2.1972245773362196,//9
        2.302585092994046,//10
        2.3978952727983707,//11
        2.4849066497880004,//12
        2.5649493574615367,//13
        2.6390573296152584,//14
        2.70805020110221,//15
        2.772588722239781,//16
        2.833213344056216,//17
        2.8903717578961645,//18
        2.9444389791664403,//19
        2.995732273553991,//20
        3.044522437723423,//21
        3.091042453358316,//22
        3.1354942159291497,//23
        3.1780538303479458,//24
        3.2188758248682006,//25
        3.258096538021482,//26
        3.295836866004329,//27
        3.332204510175204,//28
        3.367295829986474,//29
        3.4011973816621555,//30
        3.4339872044851463,//31
        3.4657359027997265,//32
        3.4965075614664802,//33
        3.5263605246161616,//34
        3.5553480614894135,//35
        3.58351893845611,//36
        3.6109179126442243,//37
        3.6375861597263857,//38
        3.6635616461296463,//39
        3.6888794541139363,//40
        3.713572066704308,//41
        3.7376696182833684,//42
        3.7612001156935624,//43
        3.784189633918261,//44
        3.8066624897703196,//45
        3.828641396489095,//46
        3.8501476017100584,//47
        3.871201010907891,//48
        3.8918202981106265,//49
        3.912023005428146,//50
        3.9318256327243257,//51
        3.9512437185814275,//52
        3.970291913552122,//53
        3.9889840465642745,//54
        4.007333185232471,//55
        4.02535169073515,//56
        4.04305126783455,//57
        4.060443010546419,//58
        4.07753744390572,//59
        4.0943445622221,//60
        4.110873864173311,//61
        4.127134385045092,//62
        4.143134726391533,//63
        4.1588830833596715,//64
        4.174387269895637,//65
        4.189654742026425,//66
        4.204692619390966,//67
        4.219507705176107,//68
        4.23410650459726,//69
        4.248495242049359,//70
        4.2626798770413155,//71
        4.276666119016055,//72
        4.290459441148391,//73
        4.30406509320417,//74
        4.31748811353631,//75
        4.330733340286331,//76
        4.343805421853684,//77
        4.356708826689592,//78
        4.3694478524670215,//79
        4.382026634673881,//80
        4.394449154672439,//81
        4.406719247264253,//82
        4.418840607796598,//83
        4.430816798843313,//84
        4.442651256490317,//85
        4.454347296253507,//86
        4.465908118654584,//87
        4.477336814478207,//88
        4.48863636973214,//89
        4.499809670330265,//90
        4.51085950651685,//91
        4.5217885770490405,//92
        4.532599493153256,//93
        4.543294782270004,//94
        4.553876891600541,//95
        4.564348191467836,//96
        4.574710978503383,//97
        4.584967478670572,//98
        4.59511985013459,//99
        4.605170185988092,//100
        4.61512051684126,//101
        4.624972813284271,//102
        4.634728988229636,//103
        4.6443908991413725,//104
        4.653960350157523,//105
        4.663439094112067,//106
        4.672828834461906,//107
        4.68213122712422,//108
        4.6913478822291435,//109
        4.700480365792417,//110
        4.709530201312334,//111
        4.718498871295094,//112
        4.727387818712341,//113
        4.736198448394496,//114
        4.74493212836325,//115
        4.7535901911063645,//116
        4.762173934797756,//117
        4.770684624465665,//118
        4.77912349311153,//119
        4.787491742782046,//120
        4.795790545596741,//121
        4.804021044733257,//122
        4.812184355372417,//123
        4.820281565605037,//124
        4.8283137373023015,//125
        4.836281906951478,//126
        4.844187086458591,//127
        4.852030263919617,//128
        4.859812404361672,//129
        4.867534450455582,//130
        4.875197323201151,//131
        4.882801922586371,//132
        4.890349128221754,//133
        4.897839799950911,//134
        4.90527477843843,//135
        4.912654885736052,//136
        4.919980925828125,//137
        4.927253685157205,//138
        4.9344739331306915,//139
        4.941642422609304,//140
        4.948759890378168,//141
        4.955827057601261,//142
        4.962844630259907,//143
        4.969813299576001,//144
        4.976733742420574,//145
        4.983606621708336,//146
        4.990432586778736,//147
        4.997212273764115,//148
        5.003946305945459,//149
        5.0106352940962555,//150
        5.017279836814924,//151
        5.0238805208462765,//152
        5.030437921392435,//153
        5.0369526024136295,//154
        5.043425116919247,//155
        5.049856007249537,//156
        5.056245805348308,//157
        5.062595033026967,//158
        5.0689042022202315,//159
        5.075173815233827,//160
        5.081404364984463,//161
        5.087596335232384,//162
        5.093750200806762,//163
        5.099866427824199,//164
        5.10594547390058,//165
        5.111987788356544,//166
        5.117993812416755,//167
        5.123963979403259,//168
        5.1298987149230735,//169
        5.135798437050262,//170
        5.14166355650266,//171
        5.147494476813453,//172
        5.153291594497779,//173
        5.159055299214529,//174
        5.1647859739235145,//175
        5.170483995038151,//176
        5.176149732573829,//177
        5.181783550292085,//178
        5.187385805840755,//179
        5.19295685089021,//180
        5.198497031265826,//181
        5.204006687076795,//182
        5.209486152841421,//183
        5.214935757608986,//184
        5.220355825078324,//185
        5.225746673713202,//186
        5.231108616854587,//187
        5.236441962829949,//188
        5.241747015059643,//189
        5.247024072160486,//190
        5.25227342804663,//191
        5.2574953720277815,//192
        5.262690188904886,//193
        5.267858159063328,//194
        5.272999558563747,//195
        5.278114659230517,//196
        5.2832037287379885,//197
        5.288267030694535,//198
        5.293304824724492,//199
        5.298317366548036,//200
        5.303304908059076,//201
        5.308267697401205,//202
        5.313205979041787,//203
        5.318119993844216,//204
        5.3230099791384085,//205
        5.327876168789581,//206
        5.332718793265369,//207
        5.337538079701318,//208
        5.342334251964811,//209
        5.3471075307174685,//210
        5.351858133476067,//211
        5.356586274672012,//212
        5.3612921657094255,//213
        5.365976015021851,//214
        5.3706380281276624,//215
        5.375278407684165,//216
        5.37989735354046,//217
        5.384495062789089,//218
        5.389071729816501,//219
        5.393627546352362,//220
        5.3981627015177525,//221
        5.402677381872279,//222
        5.407171771460119,//223
        5.4116460518550396,//224
        5.41610040220442,//225
        5.420534999272286,//226
        5.424950017481403,//227
        5.429345628954441,//228
        5.43372200355424,//229
        5.438079308923196,//230
        5.442417710521793,//231
        5.44673737166631,//232
        5.4510384535657,//233
        5.455321115357702,//234
        5.459585514144159,//235
        5.4638318050256105,//236
        5.4680601411351315,//237
        5.472270673671475,//238
        5.476463551931511,//239
        5.480638923341991,//240
        5.484796933490655,//241
        5.488937726156687,//242
        5.493061443340548,//243
        5.497168225293202,//244
        5.501258210544727,//245
        5.5053315359323625,//246
        5.5093883366279774,//247
        5.5134287461649825,//248
        5.517452896464707,//249
        5.521460917862246,//250
        5.5254529391317835,//251
        5.529429087511423,//252
        5.53338948872752,//253
        5.537334267018537,//254
        5.541263545158426//255
};

void Calculate_u8(const cv::Mat &src, cv::Mat &dst, float expTime) {
    if (src.type() != CV_32F) { return; }
    if (dst.size() != src.size() || dst.type() != CV_8U) {
        dst = cv::Mat(src.size(), CV_8U);
    }
    thread_pool tp(0, src.rows);
    tp.post([&src, &dst, expTime](int start, int end) {
        size_t buf;
//        for (int r = 0; r < src.rows; ++r) {
        for (int r = start; r < end; ++r) {
            float *pix_src = (float *) ((size_t) src.data + r * src.step);
            uchar *pix_dst = (uchar *) ((size_t) dst.data + r * dst.step);
            for (int c = 0; c < src.cols; ++c) {
                buf = 0.5 + *pix_src++ * expTime;
                *pix_dst++ = buf > 255 ? 255 : buf;
            }
        }
    });
    tp.join();
}



thread_pool::thread_pool(int start, int end, int concurrency_) : did(false) {
    concurrency = MIN(end - start, concurrency_);
    threads.resize(concurrency);
    points.resize(concurrency + 1);
    float delta = (float) (end - start) / concurrency;
    float sum = start;
    points[0] = start;
    points[concurrency] = end;
    for (int i = 1; i < concurrency; ++i) {
        sum += delta;
        points[i] = sum;
    }
}

void thread_pool::post(std::function<void(int, int)> task_to_run) {
    if (did) { return; }
    did = true;
    for (int i = 0; i < concurrency; ++i) {
        threads[i] = std::thread(task_to_run, points[i], points[i + 1]);
    }
}

void thread_pool::join() {
    if (!did) { return; }
    for (int i = 0; i < concurrency; ++i) {
        threads[i].join();
    }
}
